自定义回应(Custom Responses)

概述

Sails v.10 允许自定义服务器回应。Sails 默认附带一些常见的回应类型。可以在工程的 /api/responses 目录找到它们。只需编辑对应的 .js 文档,就可以自定义。

作为一个简单的例子,思考以下的控制器动作:

foo: function(req, res) {
   if (!req.param('id')) {
     res.status(400);
     res.view('400', {message: 'Sorry, you need to tell us the ID of the FOO you want!'});
   }
   ...
}

这个程序码通过发送一个 400 错误状态及简短问题描述来处理错误请求。然而,这个程序码有几个缺点,主要是:

  • 它不是标准化的:该代码是特定于此情况,我们必须在任何地方努力保持相同的格式
  • 它不是被分离的:当我们想要在其他地方使用类似的方法,就需要复制/贴上程序码
  • 它不是内容协商的:如果用户端期待一个 JSON 回应,那别指望了

现在,思考一下这个修改:

foo: function(req, res) {
   if (!req.param('id')) {
     res.badRequest('Sorry, you need to tell us the ID of the FOO you want!');
   }
   ...
}

这种方法具有许多优点:

  • 错误被标准化
  • 有考虑到生产环境与开发环境的日志记录
  • 错误代码是一致的
  • 有考虑到内容协商(JSON 与 HTML)
  • 可在适当的共用回应文档快速的调整 API

回应方法和文档(Responses methods and files)

任何储存在 /api/responses 文件夹的 .js 脚本可通过在控制器内呼叫 res.[responseName] 来执行。例如,可以通过呼叫 res.serverError(errors) 来执行 /api/responses/serverError.js。在回应脚本内可以通过 this.reqthis.res 取得请求及回应对象;这让实际的回应方法可以取得任意参数。(如 serverErrorerrors 参数)。

默认回应

以下的回应已绑定在所有新的 Sails 应用程序的 /api/responses 文件夹内。当用户端期望收到 JSON,会回应一个包含了 HTTP 状态代码的 status 键及任何错误相关资讯的标准化 JSON 对象。

res.serverError(errors)

这个回应会将错误标准化为适当、可读取的 Error 对象。 errors 可以是一个或多个字串或 Error 对象。它会记录所有错误到 Sails 记录器(通常是终端机),并当用户端期望收到 HTML 时回应 views/500.* 检视文档,或当用户端期望收到 JSON 时回应一个 JSON 对象。在开发模式下,错误清单会包含在回应中。在生产环境下,实际的错误会受到抑制。

res.badRequest(validationErrors, redirectTo)

对于期望收到 JSON 的请求者,这个回应包含了 400 状态码及被作为 validationErrors 所传送的任何相关资料。

对于传统的(非 AJAX)网页表单,当使用者提交无效的表单资料,这个中间件遵循了最佳做法:

  • 首先,一个暂存变数可能被填入了一个字串或语义验证错误对象。
  • 然后,将使用者重新导向回 redirectTo,即发出错误请求的来源 URL。
  • 还有,控制器和/或检视可能使用暂存变数 errors 来显示讯息或突显无效的 HTML 表单栏位。

res.notFound()

当请求者期望收到 JSON,这个回应会发送 404 状态码及一个 {status: 404} 对象。

否则,将发送位于 myApp/views/404.* 内的检视。若找不到检视,那么便发送 JSON 回应。

res.forbidden(message)

当请求者期望收到 JSON,这个回应会发送 403 状态码及 message 的内容。

否则,将发送位于 myApp/views/403.* 内的检视。若找不到检视,那么便发送 JSON 回应。

自定义回应

要加入你自己的自定义回应方法,只需新增与方法名称相同的文档到 /api/responses。该文档应该导出函数,可以附带任何你喜欢的参数。

``` /**

  • api/responses/myResponse.js *
  • This will be available in controllers as res.myResponse('foo'); */

module.exports = function(message) {

var